package output;

import lupos.AnnotationSet;
import lupos.Pos;
import lupos.Layer;
import lupos.Label;

import java.util.Collections;
import java.util.List;
import java.util.ArrayList;
import ontology.Ontology;

/** 
 * This class implements the 'example' elements in harvested lexical 
 * entry files. These have the following format:
 * 
 *   example @fn-sentence-id @fn-anno-id @fn-subcorpus @targetStart
 *           @targetEnd @targetPos @fn-status @fn-sentence-aPos @status
 *     > text #PCDATA
 *     > dependents
 *         > dependent*
 *     > postags @type
 *         > postag*
 *   
 *   The constructor method converts an AnnotationSet object into an 
 *   Example one, consulting the FrameNet ontology and the semantic 
 *   type of the lexical entry (needed to find core types, superroles 
 *   and coreness sets). 
 */

public class Example {

	public String fnSentenceId;
	public String fnAnnoId;
	public String fnSubCorpus;
	public String targetStart;
	public String targetEnd;
	public String targetPos = "";
	public String fnStatus;
	public String sentenceAPos;
	public String text;
	public String posType;
	public List<Pos> pos;
	public List<Dependent> dependents = new ArrayList<Dependent>();
	
	public Example(AnnotationSet s,Ontology o,SemanticType semtype) {
		fnSentenceId = s.sentenceId;
		fnAnnoId = s.id;
		fnSubCorpus = s.subCorpus;
		fnStatus = s.status;
		sentenceAPos = s.sentenceAPos;
		text = s.sentenceText;
		posType = s.posType;
		pos = s.pos;
		// FIND TARGET:
		for (Layer l: s.layers) {
			if (l.name.equals("Target")) {
				for (Label lb: l.labels) {
					if (lb.name.equals("Target")) {
						targetStart = lb.start;
						targetEnd = lb.end;
						for(Pos p: pos) {
							if(p.start.equals(targetStart)&&p.end.equals(targetEnd)) {
								targetPos = p.name;
								break;
							}
						}
						break;
					}
				}
				break;
			}
		}
		// FIND DEPENDENTS:
		for (Layer l: s.layers) {
			if (l.name.equals("GF")) { // only dependents with a GF are located
				for (Label lb: l.labels) {
					String syncat = "";
					String semRole = "";
					for (Layer ll: s.layers) {
						if (ll.name.equals("PT")) {
							for (Label lbl: ll.labels) {
								if (lbl.start.equals(lb.start) && lbl.end.equals(lbl.end)) {
									syncat = lbl.name;
									break;
								}
							}
						}
						else if (ll.name.equals("FE") && ll.rank.equals("1")) {
							for (Label lbl: ll.labels) {
								if (lbl.start.equals(lb.start) && lbl.end.equals(lbl.end)) {
									semRole = lbl.name;
									break;
								}
							}
						}
					}
				    dependents.add(new Dependent(lb.name,syncat,semRole,semtype.name,lb.start,lb.end,o,text.substring(Integer.parseInt(lb.start),Integer.parseInt(lb.end)+1),pos));
				}
				break;
			}
		}
		// MAKE SURE DEPENDENTS ARE ORDERED ACCORDING TO START INDEX:
		Collections.sort(dependents);
	}
	
	public String toXML() {
		String s = "    <example fn-sentence-id=\"";
		s = s + fnSentenceId + "\" fn-anno-id=\"";
		s = s + fnAnnoId + "\" fn-subcorpus=\"";
		s = s + fnSubCorpus + "\" targetStart=\"";
		s = s + targetStart + "\" targetEnd=\"";
		s = s + targetEnd + "\" targetPos=\"";
		s = s + targetPos + "\" fn-status=\"";
		s = s + fnStatus + "\" fn-sentence-aPos=\"";
		s = s + sentenceAPos + "\">\n";
		s = s + "      <text><![CDATA[" + text + "]]></text>\n";
		s = s + "      <dependents>\n";
		for(Dependent d: dependents) {
			s = s + d.toXML();
		}
		s = s + "      </dependents>\n";	
		s = s + "      <postags type=\"" + posType + "\">\n";
		for(Pos p: pos) {
			s = s + "        <postag name=\"" + p.name + "\" start=\"" + p.start + "\" end=\"" + p.end + "\"><![CDATA[" + p.text+ "]]></postag>\n";
		}
		s = s + "      </postags>\n";	
		return s + "    </example>\n";
	}
}
